home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Sample Code / Snippets / Toolbox / DragWindowGrid / DrawCode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-09  |  6.6 KB  |  254 lines  |  [TEXT/MPS ]

  1. #include <Windows.h>
  2. #include <QuickDraw.h>
  3. #include <TextUtils.h>
  4. #include <Fonts.h>
  5. #include <Memory.h>
  6.  
  7.  
  8.  
  9. /*-------------------------------------------------------------------------------------
  10.  
  11.     DragWindowGrid- a big nasty function to Drag a window along grid lines.  
  12.     Note the elegant error handling.  You should change it to make your users happy.
  13.     
  14.     You can change the size of the 'grid rects' by changing the value of kIncrement.
  15.     
  16. */
  17. void DragWindowGrid(WindowPtr win, Point pt)
  18. {
  19.     RgnHandle    dragRgn, lastDragRgn, insetGray;
  20.     GrafPtr        oldPort, tmpPort;
  21.     Point        currPt, firstMulPoint, lastMulPoint, currMulPoint;
  22.     Boolean        frameHidden;
  23.     enum        {kIncrement = 16, kBorderInset = 4};
  24.  
  25.     // Set up our regions - init our variables.
  26.     dragRgn = NewRgn(); 
  27.     lastDragRgn = NewRgn(); 
  28.     insetGray = NewRgn();
  29.     if ((dragRgn == NULL) || (lastDragRgn == NULL) || (insetGray == NULL)) {
  30.         DebugStr("\pnot enough memory- bye!");
  31.         return;
  32.     }
  33.     CopyRgn(GetGrayRgn(), insetGray);
  34.     if (MemError() != noErr) {
  35.         DebugStr("\pnot enough memory- bye!");
  36.         return;
  37.     }
  38.  
  39.     InsetRgn(insetGray, kBorderInset, kBorderInset);
  40.     frameHidden = false;
  41.  
  42.     // Set up a port to draw into, and save off the old
  43.     tmpPort = (GrafPtr)NewPtr(sizeof(GrafPort));
  44.     if (tmpPort == NULL) {
  45.         DebugStr("\pnot enough memory- bye!");
  46.         return;
  47.     }
  48.     GetPort(&oldPort);
  49.     OpenPort(tmpPort);
  50.     CopyRgn(GetGrayRgn(), tmpPort->visRgn);
  51.     if (MemError() != noErr) {
  52.         DebugStr("\pnot enough memory- bye!");
  53.         return;
  54.     }
  55.     tmpPort->portRect = (*GetGrayRgn())->rgnBBox;
  56.     SetPort(tmpPort);
  57.     
  58.     PenMode(patXor);
  59.     PenPat(&qd.gray);
  60.  
  61.     // Set the incoming point to be on a multiple of kIncrement,
  62.     // to make later calculations easier.
  63.     currMulPoint.h = pt.h + (kIncrement/2);
  64.     currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement;
  65.     currMulPoint.v = pt.v + (kIncrement/2);
  66.     currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement;
  67.  
  68.     firstMulPoint = lastMulPoint = currMulPoint;
  69.  
  70.     CopyRgn(((WindowPeek)win)->strucRgn, dragRgn);
  71.     if (MemError() != noErr) {
  72.         DebugStr("\pnot enough memory- bye!");
  73.         return;
  74.     }
  75.  
  76.     CopyRgn(((WindowPeek)win)->strucRgn, lastDragRgn);
  77.     if (MemError() != noErr) {
  78.         DebugStr("\pnot enough memory- bye!");
  79.         return;
  80.     }
  81.  
  82.     // Draw the first framed region, which will follow the mouse
  83.     // on the screen
  84.     FrameRgn(lastDragRgn);
  85.  
  86.     while (WaitMouseUp() == true) {
  87.         // Now track the mouse, and when it moves enough make the framed
  88.         // region move as well.
  89.         GetMouse(&currPt);
  90.     
  91.         // Set the new point to be on a multiple of kIncrement
  92.         currMulPoint.h = currPt.h + (kIncrement/2);
  93.         currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement;
  94.         currMulPoint.v = currPt.v + (kIncrement/2);
  95.         currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement;
  96.  
  97.         // Should we be showing the frame region ??
  98.         if (PtInRgn(currPt, insetGray) == false) {
  99.             // It's somewhere near the edges, so hide the frame
  100.             if (frameHidden == false)
  101.                 // if it's not hidden already, hide it now
  102.                 FrameRgn(lastDragRgn);
  103.             frameHidden = true;
  104.         }
  105.         else {
  106.             // else, the frame should be shown if it's hidden
  107.             if (frameHidden == true) {
  108.                 FrameRgn(lastDragRgn);
  109.                 frameHidden = false;
  110.             }
  111.         }
  112.     
  113.         // Has the mouse moved ?
  114.         if (currMulPoint != lastMulPoint) {            
  115.             // The mouse coordinates have changed enough to adjust the window,
  116.             // so move the frame accordingly
  117.             OffsetRgn(dragRgn, currMulPoint.h - lastMulPoint.h, currMulPoint.v - lastMulPoint.v);
  118.  
  119.             if (frameHidden == false) {
  120.                 // Only show the frame if we're allowed to.
  121.                 FrameRgn(dragRgn);        
  122.                 FrameRgn(lastDragRgn);
  123.             }
  124.             lastMulPoint = currMulPoint;
  125.             CopyRgn(dragRgn, lastDragRgn);
  126.             if (MemError() != noErr) {
  127.                 DebugStr("\pnot enough memory- bye!");
  128.                 return;
  129.             }
  130.         }    
  131.     }
  132.     
  133.     if (frameHidden == false)
  134.         // If frameHidden is true, there's no need to erase the final
  135.         // frame.
  136.         FrameRgn(lastDragRgn);
  137.  
  138.     if ((lastMulPoint != firstMulPoint) && (frameHidden == false)) {
  139.         // The mouse has moved from its original position and is
  140.         // somewhere on the screen, so move the window accordingly.
  141.         Point    globalPt, diffPt, contPt = {0, 0};
  142.  
  143.         // Calculate the difference between the strucRgn's 0, 0 and
  144.         // the window's content region 0, 0.  Remember that MoveWindow
  145.         // moves the window's *content* to the coordinate specified, and
  146.         // we want to move the window's structure to fit in the lastDragRgn
  147.         SetPort(win);
  148.         // LocalToGlobal works much better when the port is set up...
  149.         LocalToGlobal(&contPt);
  150.         SetPort(tmpPort);
  151.         diffPt.h = contPt.h - (*((WindowPeek)win)->strucRgn)->rgnBBox.left;
  152.         diffPt.v = contPt.v - (*((WindowPeek)win)->strucRgn)->rgnBBox.top;
  153.         
  154.         globalPt.h = (*lastDragRgn)->rgnBBox.left;
  155.         globalPt.v = (*lastDragRgn)->rgnBBox.top;
  156.         LocalToGlobal(&globalPt);
  157.         globalPt.h += diffPt.h;
  158.         globalPt.v += diffPt.v;
  159.         MoveWindow(win, globalPt.h, globalPt.v, true);
  160.     }
  161.  
  162.     // Close the port and tear everything down
  163.     ClosePort(tmpPort);
  164.     SetPort(oldPort);
  165.     DisposeRgn(dragRgn);
  166.     DisposeRgn(insetGray);
  167.     DisposeRgn(lastDragRgn);
  168.     
  169. }
  170.  
  171.  
  172. /*-------------------------------------------------------------------------------------*/
  173.  
  174. void DrawIt(WindowPtr win)
  175. {
  176.     short         origFont, origSize;
  177.     
  178.     origFont = win->txFont;
  179.     origSize = win->txSize;
  180.     TextFont(courier);
  181.     TextSize(12);
  182.  
  183.     ForeColor(redColor);
  184.     PaintRect(&(*win).portRect);
  185.     ForeColor(blackColor);
  186.  
  187.     MoveTo(20, 20);
  188.     DrawString("\pDrag this window.");
  189.  
  190.     TextFont(origFont);
  191.     TextSize(origSize);
  192. }
  193.  
  194.  
  195. /*-------------------------------------------------------------------------------------*/
  196.  
  197. pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin)
  198. {
  199. #pragma unused (pixelDepth, dFlags, theDevice)
  200.     GrafPtr        savePort;
  201.  
  202.     GetPort(&savePort);
  203.     SetPort((GrafPtr)theWin);
  204.  
  205.     DrawIt((WindowPtr)theWin);
  206.  
  207.     SetPort(savePort);
  208. }
  209.  
  210.  
  211. /*-------------------------------------------------------------------------------------*/
  212.  
  213. void CreateNewWindow(void)
  214. {
  215.     Rect winDimension;
  216.     
  217.     SetRect(&winDimension, 60, 60, 460, 260);
  218.     (void)NewCWindow(0L, &winDimension, "\pSample", true, noGrowDocProc,
  219.                             (WindowPtr)-1L, true, 0L);
  220. }
  221.  
  222.  
  223. /*-------------------------------------------------------------------------------------*/
  224.  
  225. void PreEventLoop(void)
  226. {
  227.     CreateNewWindow();
  228. }
  229.  
  230.  
  231. /*-------------------------------------------------------------------------------------*/
  232.  
  233. void DoUpdate(WindowPtr thisWindow)
  234. {
  235.     static DeviceLoopDrawingUPP    procForDeviceLoop = nil;
  236.  
  237.     SetPort(thisWindow);
  238.  
  239.     if ( procForDeviceLoop == nil )
  240.         procForDeviceLoop = NewDeviceLoopDrawingProc(DrawWindowContent);    
  241.     
  242.     BeginUpdate(thisWindow);
  243.     DeviceLoop(thisWindow->visRgn, procForDeviceLoop, (long)thisWindow, singleDevices);
  244.     EndUpdate(thisWindow);
  245. }
  246.  
  247.  
  248. /*-------------------------------------------------------------------------------------*/
  249.  
  250. void PostEventLoop(void)
  251. {
  252. }
  253.  
  254.